<template>
  <div class="form-preview" :style="{ height: currentDevice === 'pc' ? props.height : '667px', width: currentDevice === 'pc' ? '100%' : '375px', padding: props.simple ? '0' : '70px 0' }">
    <!-- 添加背景层 -->
    <div class="background-layer" :style="getBackgroundStyle"></div>
    <!-- 设备切换 -->
    <div class="form-device" v-if="props.showDevice">
      <el-button-group>
        <el-button round :type="currentDevice==='pc'?'primary':''" @click="changeDevice('pc')">电脑端</el-button>
        <el-button round :type="currentDevice==='phone'?'primary':''" @click="changeDevice('phone')">手机端</el-button>
      </el-button-group>
    </div>
    <!-- 表单内容 -->
    <div class="form-center" :style="{ width: props.simple ? '100%' : currentDevice === 'pc' ? '80%' : '95%'}">
      <el-scrollbar>
        <!-- Logo -->
        <div v-if="formData.formAppearanceInfo.showLogo" class="form-logo">
          <img :src="formData.formAppearanceInfo.logoImg" alt="logo" />
        </div>
        <!-- 表单头部 -->
        <div
          v-if="formData.formAppearanceInfo.headerImg"
          class="form-header"
          :style="{
            backgroundImage: `url(${formData.formAppearanceInfo.headerImg})`,
            backgroundSize: 'cover',
            backgroundPosition: 'center'
          }"
        ></div>
        <!-- 表单标题 -->
        <h2 class="form-title">
          {{ formData.label }}
        </h2>
        <!-- 表单描述 -->
        <div v-if="formData.description" class="form-description">
          {{ formData.description }}
        </div>
        <!-- 表单来源 -->
        <div v-if="formData.publishSetting.showSourceName && formData.sourceId" class="form-source">
          来源：{{ formData.sourceName }}
        </div>
        <!-- 分页信息 -->
        <el-divider v-if="formData.hasPageCmp" style="margin: 24px 0">
          <span class="form-page">第{{ currentPage }}页/共{{ totalPages }}页</span>
        </el-divider>
        <!-- 表单内容 -->
        <div class="form-content" :style="{ padding: currentDevice === 'pc' ? '20px 50px' : '20px' }">
          <el-form
            ref="formRef"
            :model="form"
            :rules="formRules"
            :validate-on-rule-change="false"
            label-width="auto"
            label-position="top"
          >
            <!-- 当前页显示的题目 -->
            <el-form-item
              v-for="question in currentPageQuestions"
              :key="question.formItemId"
              :label="`${getQuestionIndex(question)}. ${question.label}`"
              :id="`${question.formItemId}`"
              :prop="question.formItemId"
              label-position="top"
              v-show="currentPageQuestions.includes(question)"
            >
              <div
                class="question-content"
                :style="{ width: question.width ? question.width + 'px' : '100%' }"
              >
                <div v-if="question.description" class="question-description">
                  {{ question.description }}
                </div>
                <component
                  :is="getComponent(question.type)"
                  v-model:modelValue="form[question.formItemId]"
                  v-model:formRules="formRules"
                  :setting="question"
                  :disabled="props.disabled"
                />
              </div>
            </el-form-item>
    
            <!-- 其他页的题目（隐藏） -->
            <el-form-item
              v-for="question in displayQuestions.filter(
                (q) => q.type !== 'pagenation' && !currentPageQuestions.includes(q)
              )"
              :key="question.formItemId"
              :prop="question.formItemId"
              style="display: none"
            >
              <component
                :is="getComponent(question.type)"
                v-model:modelValue="form[question.formItemId]"
                v-model:formRules="formRules"
                :setting="question"
                :disabled="props.disabled"
              />
            </el-form-item>
          </el-form>
          <!-- 分页按钮 -->
          <div v-if="formData.hasPageCmp" class="pagination-buttons">
            <el-button v-if="currentPage > 1" @click="handlePrevPage"> 上一页 </el-button>
            <el-button v-if="currentPage < totalPages" type="primary" @click="handleNextPage">
              下一页
            </el-button>
          </div>
        </div>
      </el-scrollbar>
    </div>
  </div>
</template>

<script setup>
/*应用到弹窗或抽屉中时，最大宽度设置为875px，计算方式为：由于设置题目时，表单项最大宽度为600px，加上form-content内边距100px，加上form-preview只占80%宽度。700 / 0.8 = 875  简洁模式为700 */
import { ref, markRaw, computed, watch } from 'vue'
import FormInput from './formItems/FormInput.vue'
import FormTextarea from './formItems/FormTextarea.vue'
import FormRadio from './formItems/FormRadio.vue'
import FormDate from './formItems/FormDate.vue'
import FormCheckbox from './formItems/FormCheckbox.vue'
import FormSelectSingle from './formItems/FormSelectSingle.vue'
import FormSelectMultiple from './formItems/FormSelectMultiple.vue'
import FormFileUpload from './formItems/FormFileUpload.vue'
import FormImgUpload from './formItems/FormImgUpload.vue'

const props = defineProps({
  height: {
    type: String,
    default: '56vh'
  },
  // 回显填写详情时，禁用表单项
  disabled: {
    type: Boolean,
    default: true
  },
  // 简洁模式，不展示外观，只展示form-center
  simple: {
    type: Boolean,
    default: false
  },
  // 是否展示设备切换
  showDevice: {
    type: Boolean,
    default: false
  },
  // 表单信息，如标题，外观，表单项等
  formData: {
    type: Object,
    required: true
  },
  // 表单填写值
  modelValue: {
    type: Object,
    default: () => ({})
  }
})

const emit = defineEmits(['update:modelValue'])

// 设备切换
const currentDevice = ref('pc')
const changeDevice = (device) => {
  currentDevice.value = device
}

// 组件注册
const components = ref({
  input: markRaw(FormInput),
  textarea: markRaw(FormTextarea),
  radio: markRaw(FormRadio),
  date: markRaw(FormDate),
  checkbox: markRaw(FormCheckbox),
  selectSingle: markRaw(FormSelectSingle),
  selectMultiple: markRaw(FormSelectMultiple),
  fileUpload: markRaw(FormFileUpload),
  imgUpload: markRaw(FormImgUpload)
})

const getComponent = (type) => {
  return components.value[type] || null
}

const formRef = ref(null)
const formRules = ref({})
const form = ref(props.modelValue)

// 监听表单值变化
watch(
  form,
  (newVal) => {
    emit('update:modelValue', newVal)
  },
  { deep: true }
)

// 计算要显示的题目
const displayQuestions = computed(() => {
  const questions = props.formData.formItemList
  const result = []
  const connectedIds = new Set()
  const shouldShowConnected = new Set()

  questions.forEach((question) => {
    if (question.connect) {
      question.default.forEach((option) => {
        if (option.connect?.length > 0) {
          option.connect.forEach((id) => connectedIds.add(id))
        }
      })
    }
  })

  questions.forEach((question) => {
    if (question.connect && form.value[question.formItemId]) {
      const selectedOption = question.default.find(
        (opt) =>
          opt.label === form.value[question.formItemId] ||
          opt.placeholder === form.value[question.formItemId]
      )
      if (selectedOption && selectedOption.connect?.length > 0) {
        selectedOption.connect.forEach((id) => shouldShowConnected.add(id))
      }
    }
  })

  questions.forEach((question) => {
    if (question.type === 'pagenation') {
      result.push(question)
      return
    }

    if (connectedIds.has(question.formItemId)) {
      if (shouldShowConnected.has(question.formItemId)) {
        result.push(question)
      }
      return
    }

    result.push(question)

    if (
      props.formData.onePageOneQs &&
      props.formData.hasPageCmp &&
      questions.indexOf(question) < questions.length - 1
    ) {
      result.push({ type: 'pagenation' })
    }
  })

  return result
})

// 获取题目序号
const getQuestionIndex = (question) => {
  const realQuestions = displayQuestions.value.filter((q) => q.type !== 'pagenation')
  return realQuestions.indexOf(question) + 1
}

// 分页相关
const currentPage = ref(1)

const questionGroups = computed(() => {
  if (!props.formData.hasPageCmp) {
    return [displayQuestions.value]
  }

  const groups = []
  let currentGroup = []
  displayQuestions.value.forEach((question) => {
    if (question.type === 'pagenation') {
      if (currentGroup.length > 0) {
        groups.push(currentGroup)
        currentGroup = []
      }
    } else {
      currentGroup.push(question)
    }
  })

  if (currentGroup.length > 0) {
    groups.push(currentGroup)
  }

  return groups
})

const currentPageQuestions = computed(() => {
  return questionGroups.value[currentPage.value - 1] || []
})

const totalPages = computed(() => questionGroups.value.length)

const handlePrevPage = () => {
  if (currentPage.value > 1) {
    currentPage.value--
  }
}

const handleNextPage = () => {
  if (currentPage.value < totalPages.value) {
    currentPage.value++
  }
}

// 计算背景样式
const getBackgroundStyle = computed(() => {
  if (props.simple) {
    return {
      background: 'transparent'
    }
  }
  const { backgroundType, backgroundColor, backgroundImg } =
    props.formData.formAppearanceInfo
  if (backgroundType === 'img' && backgroundImg) {
    return {
      background: `url(${backgroundImg}) center/cover no-repeat fixed`,
      filter: 'blur(3px)',
      position: 'absolute',
      top: 0,
      left: 0,
      right: 0,
      bottom: 0,
      zIndex: 0
    }
  }
  return {
    background: backgroundColor || '#f6f6f6'
  }
})

// 暴露方法给父组件
defineExpose({
  formRef,
  currentPage,
  totalPages
})
</script>

<style lang="scss" scoped>
.form-preview {
  position: relative;
  display: flex;
  justify-content: center;
  padding: 70px 0;
  margin: 0 auto;
  width: 100%;
  overflow: hidden;
  transition: width 0.3s;

  .form-device {
    position: absolute;
    top: 10px;
    z-index: 2;
    display: flex;
    justify-content: center;
    
  }
}
.form-center {
  z-index: 2;
  width: 80%;
  max-width: 700px;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  overflow: hidden;

  .form-logo {
    height: 50px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 10px;
    background: #fff;

    img {
      height: 100%;
      object-fit: contain;
    }
  }

  .form-header {
    height: 200px;
    background: #ccc;
    transition: background-image 0.3s;
  }

  .form-title,
  .form-description {
    padding: 0 100px;
    margin: 20px 0 0;
    text-align: center;
    color: #333;
    font-weight: 600;
    font-size: 28px;
    word-break: break-all;
    white-space: pre-wrap;
  }

  .form-description {
    margin-top: 10px;
    font-size: 14px;
    font-weight: 400;
    color: #606266;
  }

  .form-source {
    margin: 20px 0 30px;
    text-align: center;
    font-size: 14px;
    color: #606266;
  }

  .form-page {
    font-size: 16px;
    font-weight: bold;
  }

  .form-content {
    padding: 20px 50px;

    .el-form {
      max-width: 800px;
      margin: 0 auto;

      .el-form-item {
        scroll-margin-top: 20px;
        margin-bottom: 30px;

        .question-content {
          padding-left: 21px;
          box-sizing: border-box;

          .question-description {
            margin-bottom: 10px;
            line-height: 14px;
            font-size: 14px;
            color: #606266;
          }
        }

        :deep(.el-form-item__error) {
          margin-top: 5px;
          padding-left: 21px;
        }
      }
      :deep(.el-form-item:not(.is-required) .el-form-item__label) {
        margin-left: 21px;
      }
    }
  }
}

:deep(.el-form .el-form-item .el-form-item__label) {
  font-size: 16px;
  font-weight: bold;
}

.pagination-buttons {
  display: flex;
  justify-content: center;
  gap: 16px;
  margin-top: 20px;
}
</style>